---
title: "NBA Betting Dashboard"
output:
flexdashboard::flex_dashboard:
theme:
version: 4
bootswatch: default
navbar-bg: "#3b5998"
orientation: columns
vertical_layout: fill
source_code: embed
---
<style>
.chart-title
{
/* chart_title */
font-size: 18px;
font-family: Arial;
}
body
{
/* Normal */
font-size: 16px;
}
</style>
```{css color tabs}
/* Set font color of inactive tab to green */
.nav-tabs-custom .nav-tabs > li > a
{
color: blue;
}
/* Set font color of active tab to red */
.nav-tabs-custom .nav-tabs > li.active > a
{
color: purple;
}
/* To set color on hover */
.nav-tabs-custom .nav-tabs > li.active > a:hover
{
color: black;
}
<style type="text/css"> .sidebar
{
overflow: auto;
}
</style>
```
```{r setup, include=FALSE}
library(flexdashboard)
```
```{r packages}
pacman::p_load(rvest, tidyverse, ggplot2, stringr, esquisse, plotly)
```
```{r scraping & cleaning (salary)}
link1 = "https://hoopshype.com/salaries/players/"
page1 = read_html(link1)
name = page1 %>%
html_nodes("tbody .name") %>% html_text()
salary = page1 %>%
html_nodes("tbody .hh-salaries-sorted") %>% html_text()
name <- gsub("\t", "", name)
name <- gsub("\n", "", name)
salary <- gsub("\n", "", salary)
salary <- gsub("\t", "", salary)
salary <- gsub("\\$", "", salary)
salary <- gsub(",", "", salary)
nba_salary <- data.frame(name, salary)
nba_salary$salary <- as.numeric(nba_salary$salary)
```
```{r scraping & cleaning (stats)}
nba_stats = data.frame()
for (pages in c(1,2,3))
{
link2 = paste0("https://basketball.realgm.com/nba/stats/2023/Averages/Qualified/points/All/desc/", pages, "/Regular_Season")
page2 = read_html(link2)
name = page2 %>%
html_nodes(".nowrap") %>% html_text()
team = page2 %>%
html_nodes(".nowrap+ td") %>% html_text()
mpg = page2 %>%
html_nodes("td:nth-child(3)") %>% html_text()
gp = page2 %>%
html_nodes("td:nth-child(4)") %>% html_text()
mpg = page2 %>%
html_nodes("td:nth-child(5)") %>% html_text()
ppg = page2 %>%
html_nodes("td:nth-child(6)") %>% html_text()
fgm = page2 %>%
html_nodes("td:nth-child(7)") %>% html_text()
fga = page2 %>%
html_nodes("td:nth-child(8)") %>% html_text()
fgp = page2 %>%
html_nodes("td:nth-child(9)") %>% html_text()
tpm = page2 %>%
html_nodes("td:nth-child(10)") %>% html_text()
tpa = page2 %>%
html_nodes("td:nth-child(11)") %>% html_text()
tpp = page2 %>%
html_nodes("td:nth-child(12)") %>% html_text()
ftm = page2 %>%
html_nodes("td:nth-child(13)") %>% html_text()
fta = page2 %>%
html_nodes("td:nth-child(14)") %>% html_text()
ftp = page2 %>%
html_nodes("td:nth-child(15)") %>% html_text()
orb = page2 %>%
html_nodes("td:nth-child(16)") %>% html_text()
drb = page2 %>%
html_nodes("td:nth-child(17)") %>% html_text()
rpg = page2 %>%
html_nodes("td:nth-child(18)") %>% html_text()
apg = page2 %>%
html_nodes("td:nth-child(19)") %>% html_text()
spg = page2 %>%
html_nodes("td:nth-child(20)") %>% html_text()
bpg = page2 %>%
html_nodes("td:nth-child(21)") %>% html_text()
tov = page2 %>%
html_nodes("td:nth-child(22)") %>% html_text()
pf = page2 %>%
html_nodes("td:nth-child(23)") %>% html_text()
nba_stats <- rbind(nba_stats, as.data.frame(cbind(name, team, gp, mpg, ppg, fgm, fga, fgp, tpm, tpa, tpp, ftm, fta, ftp, orb, drb, rpg, apg, spg, bpg, tov, pf)))
}
nba_stats <- nba_stats %>% mutate_at(c("ppg", "fgm", "fga",
"fgp", "tpm", "tpa",
"tpp", "ftm", "fta",
"ftp", "orb", "drb",
"rpg", "apg", "spg",
"bpg", "tov", "pf", "mpg"), as.numeric)
```
```{r merge data}
nba <- left_join(nba_stats, nba_salary, by = "name")
nba$team <- as.factor(nba$team)
nba <- na.omit(nba)
tpar <- rep(NA, 259)
for (i in 1:259)
{
tpar[i] = nba$ppg[i] + nba$apg[i] + nba$rpg[i]
}
nba <- as.data.frame(cbind(nba, tpar))
per <- rep(NA, 259)
for (i in 1:259)
{
per[i] = (nba$ppg[i] + nba$apg[i] + nba$rpg[i] + nba$spg[i] + nba$bpg[i] -
nba$tov[i] - ((nba$fga[i] + nba$tpa[i] + nba$fta[i]) - (nba$fgm[i] + nba$tpm[i] + nba$ftm[i])))
}
nba <- as.data.frame(cbind(nba, per))
perm <- rep(NA, 259)
for (i in 1:259)
{
perm[i] = nba$per[i]/nba$mpg[i]
}
nba <- as.data.frame(cbind(nba, perm))
nba$perm <- round(nba$perm, digits = 2)
```
EDA-1
===
Row {data-width=650}
-----------------------------------------------------------------------
### Data Table (Offensive Summary)
```{r}
DT::datatable(nba, rownames = FALSE,
options = list(columnDefs = list(list(className = 'dt-center', targets = 1:22))))
```
EDA-2
===
Row {data-width=650}
-----------------------------------------------------------------------
### Data Table (Betting Summary)
```{r scraping & cleaning}
link3 = "https://www.covers.com/sport/basketball/nba/statistics/team-betting/2022-2023"
page3 = read_html(link3)
teamName = page3 %>%
html_nodes("td:nth-child(2)") %>% html_text()
againstSpread = page3 %>%
html_nodes("td:nth-child(3)") %>% html_text()
againstSpreadP = page3 %>%
html_nodes("td:nth-child(4)") %>% html_text()
W_L = page3 %>%
html_nodes("td:nth-child(5)") %>% html_text()
overUnder = page3 %>%
html_nodes("td:nth-child(6)") %>% html_text()
pointsPerGame = page3 %>%
html_nodes("td:nth-child(7)") %>% html_text()
pointsAgainst = page3 %>%
html_nodes("td:nth-child(8)") %>% html_text()
pointMarginPerGame = page3 %>%
html_nodes("td:nth-child(9)") %>% html_text()
teamName <- gsub(" ", "", teamName)
teamName <- gsub("\r", "", teamName)
teamName <- gsub("\n", "", teamName)
nba_bet <- as.data.frame(cbind(teamName, againstSpread, againstSpreadP, W_L, overUnder, pointsPerGame, pointsAgainst, pointMarginPerGame))
```
```{r data table 2}
DT::datatable(nba_bet, rownames = FALSE,
options = list(columnDefs = list(list(className = 'dt-center', targets = 1:7))))
```
EDA-3
===
Row {.tabset data-width=650}
-----------------------------------------------------------------------
### Scatter Plot (PPG vs. Salary)
```{r EDA 3}
plot1 <- ggplot(nba, aes(x = salary, y = ppg,
text = paste0("Player: ", name, "\n", "PPG: ", ppg, "\n", "Salary: ", salary))) +
geom_point(shape = "", colour = "#45b6fe") + labs(x = "Salary", y = "PPG", title = "NBA Points Per Game vs. Salary", subtitle = "2022-2023 Season") +
theme_classic()
font1 <- list(family = "Mono", size = 15, color = "black")
label1 <- list(bgcolor = "lightblue", font = font1)
ggplotly(plot1, tooltip = "text") %>%
style(hoverlabel = label1) %>%
layout(font = font1)
```
### Scatter Plot (RPG vs. Salary)
```{r EDA 4}
plot2 <- ggplot(nba, aes(x = salary, y = rpg,
text = paste0("Player: ", name, "\n", "RPG: ", rpg, "\n", "Salary: ", salary))) +
geom_point(shape = "bullet", colour = "#296d98") + labs(x = "Salary", y = "RPG", title = "NBA Rebounds Per Game vs. Salary", subtitle = "2022-2023 Season") +
theme_classic()
font2 <- list(family = "Mono", size = 15, color = "black")
label2 <- list(bgcolor = "lightblue", font = font2)
ggplotly(plot2, tooltip = "text") %>%
style(hoverlabel = label2) %>%
layout(font = font2)
```
### Scatter Plot (APG vs. Salary)
```{r EDA 5}
plot3 <- ggplot(nba, aes(x = salary, y = apg,
text = paste0("Player: ", name, "\n", "APG: ", apg, "\n", "Salary: ", salary))) +
geom_point(shape = "bullet", colour = "#0e2433") +
labs(x = "Salary", y = "PPG", title = "NBA Assists Per Game vs. Salary", subtitle = "2022-2023 Season") +
theme_classic()
font3 <- list(family = "Mono", size = 15, color = "black")
label3 <- list(bgcolor = "lightblue", font = font3)
ggplotly(plot3, tooltip = "text") %>%
style(hoverlabel = label3) %>%
layout(font = font3)
```
### Scatter Plot (TPAR vs. Salary)
```{r EDA 6}
plot4 <- ggplot(nba, aes(x = salary, y = tpar,
text = paste0("Player: ", name, "\n", "TPAR: ", tpar, "\n", "Salary: ", salary))) +
geom_point(shape = "bullet", colour = "#0e2433") +
labs(x = "Salary", y = "PPG", title = "NBA Total Points + Rebounds + Assists Per Game vs. Salary", subtitle = "2022-2023 Season") +
theme_classic()
font4 <- list(family = "Mono", size = 15, color = "black")
label4 <- list(bgcolor = "lightblue", font = font4)
ggplotly(plot4, tooltip = "text") %>%
style(hoverlabel = label4) %>%
layout(font = font4)
```
### Scatter Plot (PER vs. Salary)
```{r EDA 7}
plot5 <- ggplot(nba, aes(x = salary, y = per,
text = paste0("Player: ", name, "\n", "PER: ", per, "\n", "Salary: ", salary))) +
geom_point(shape = "bullet", colour = "#0e7733") +
labs(x = "Salary", y = "PER", title = "NBA Player Efficiency Rating (PER) vs. Salary", subtitle = "2022-2023 Season") +
theme_classic()
font5 <- list(family = "Mono", size = 15, color = "black")
label5 <- list(bgcolor = "lightblue", font = font5)
ggplotly(plot5, tooltip = "text") %>%
style(hoverlabel = label5) %>%
layout(font = font5)
```
### Scatter Plot (PERM vs. Salary)
```{r EDA 8}
plot6 <- ggplot(nba, aes(x = salary, y = perm,
text = paste0("Player: ", name, "\n", "PERM: ", round(perm, digits = 2), "\n", "Salary: ", salary))) +
geom_point(shape = "bullet", colour = "maroon") +
labs(x = "Salary", y = "PER", title = "NBA Player Efficiency Rating per Minute (PERM) vs. Salary", subtitle = "2022-2023 Season") +
theme_classic()
font6 <- list(family = "Mono", size = 15, color = "black")
label6 <- list(bgcolor = "lightblue", font = font6)
ggplotly(plot6, tooltip = "text") %>%
style(hoverlabel = label6) %>%
layout(font = font6)
```